Skip to content

Comments

Add persistent flash messages and M3U8 single-stream mode#88

Merged
thehack904 merged 11 commits intodevfrom
copilot/fix-flash-message-visibility
Feb 16, 2026
Merged

Add persistent flash messages and M3U8 single-stream mode#88
thehack904 merged 11 commits intodevfrom
copilot/fix-flash-message-visibility

Conversation

Copy link
Contributor

Copilot AI commented Feb 16, 2026

Validation errors (duplicate names, invalid URLs) were flashing too quickly for users to read. Single-stream M3U8 support existed in backend but had no dedicated UI path, forcing users to duplicate URLs across both fields.

Changes

Flash message persistence

  • Messages now persist 8s with fade-out animation
  • Manual dismiss via × button
  • Sticky positioning (top: 20px, z-index: 1000) maintains visibility during scroll
  • Category-based styling (success/warning/error/info) for both themes

Templates/CSS:

<div class="flash-message flash-{{ category }}">
  <span class="flash-content">{{ message }}</span>
  <button class="flash-close">&times;</button>
</div>

JavaScript auto-dismiss:

setTimeout(() => {
  flashMessages.forEach(msg => {
    msg.classList.add('fade-out');
    setTimeout(() => msg.remove(), 500);
  });
}, 8000);

Single-stream M3U8 mode

  • Radio toggle: Standard Playlist Mode (XML + M3U) vs Single Stream Mode (M3U8 only)
  • JavaScript conditionally shows fields and toggles required attributes
  • Backend uses M3U8 URL for both XML and M3U when tuner_mode=single_stream

Backend handling (app.py):

if tuner_mode == "single_stream":
    m3u8_stream_url = request.form.get("m3u8_stream_url", "").strip()
    add_tuner(name, m3u8_stream_url, m3u8_stream_url)  # Same URL for both fields
else:
    # Standard mode: separate XML and M3U URLs
    add_tuner(name, xml_url, m3u_url)

Screenshots

Standard mode (default):
Standard mode

Single stream mode active:
Single stream mode

Backward compatibility

Existing tuners continue working unchanged. Standard mode remains the default.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • example.com
    • Triggering command: /usr/bin/python3 python3 app.py (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

Fix Flash Message Visibility & Add M3U8 Single-Stream Field

Objective

Improve user experience by making validation error messages persist longer and adding a dedicated field for single-stream M3U8 URLs.

Issues to Address

1. Flash Messages Disappear Too Quickly

Problem: Validation error messages (duplicate name, invalid URL, unreachable URL) flash so quickly users can't read them.

Solution:

  • Modify flash message display to persist for at least 5-8 seconds
  • Add dismiss button so users can manually close messages
  • Consider using CSS animations for smoother fade-out
  • Implement sticky positioning so messages stay visible while scrolling

Files to modify:

  • templates/base.html or templates/change_tuner.html - Update flash message display logic
  • static/css/change_tuner.css or main CSS - Add styles for persistent messages
  • Add JavaScript to handle auto-dismiss after delay and manual dismiss button

Implementation details:

// Add to change_tuner.html or create new JS file
setTimeout(() => {
    const flashMessages = document.querySelectorAll('.flash-message');
    flashMessages.forEach(msg => {
        msg.classList.add('fade-out');
        setTimeout(() => msg.remove(), 500);
    });
}, 8000); // 8 second delay
/* Ensure messages are visible and dismissible */
.flash-message {
    position: sticky;
    top: 20px;
    z-index: 1000;
    padding: 12px 20px;
    margin-bottom: 15px;
    border-radius: 6px;
    opacity: 1;
    transition: opacity 0.5s ease;
}

.flash-message.fade-out {
    opacity: 0;
}

.flash-message .close-btn {
    float: right;
    cursor: pointer;
    font-weight: bold;
    margin-left: 10px;
}

2. Add Dedicated M3U8 Single-Stream Field

Problem: Single-stream M3U8 support is hidden. Users need a clear option to add single-stream sources.

Solution:
Add a third input option in the tuner management UI:

  • Keep existing: XML URL (.xml) and M3U URL (.m3u)
  • Add new: M3U8 Stream URL (single-stream mode)

UI Design:

┌─────────────────────────────────────────────┐
│ Add new tuner                               │
├─────────────────────────────────────────────┤
│ Tuner Name: [_______________]              │
│                                             │
│ ○ Standard Playlist Mode                   │
│   XML URL (.xml):  [_______________]       │
│   M3U URL (.m3u):  [_______________]       │
│                                             │
│ ○ Single Stream Mode                       │
│   M3U8 Stream URL: [_______________]       │
│   (Direct link to .m3u8 stream)            │
│                                             │
│ [Add Tuner]                                │
└─────────────────────────────────────────────┘

Implementation Requirements:

  1. Update templates/change_tuner.html:

    • Add radio buttons to toggle between "Standard Playlist Mode" and "Single Stream Mode"
    • Show/hide relevant fields based on selection
    • Add help text explaining the difference
  2. Update app.py /change_tuner route (around line 745-760):

    • Check which mode is selected
    • If "Single Stream Mode" is selected:
      • Get the m3u8_stream_url from form
      • Generate a temporary M3U playlist content with single entry
      • Store it or handle it appropriately in the database
    • Validate accordingly
  3. Update add_tuner() function:

    • Add optional parameter stream_mode (default False)
    • If stream_mode=True:
      • Accept single M3U8 URL
      • Auto-generate channel name from URL
      • Set xml to empty or use m3u8_url for both fields
      • Create minimal playlist entry
  4. JavaScript for UI Toggle:

// Add to change_tuner.html
document.querySelectorAll('input[name="tuner_mode"]').forEach(radio => {
    radio.addEventListener('change', (e) => {
        const isStandard = e.target.value === 'standard';
        document.getElementById('standard-fields').style.display = isStandard ? 'block' : 'none';
        document.getElementById('stream-fields').style.display = isStandard ? 'none' : 'block';
    });
});
  1. Backend handling in add_tuner() or new helper function:
def add_tuner_single_stream(name, m3u8_url):
    """Add a tuner with a single M3U8 stream URL."""
    # Validate URL
    if not m3u8_url.startswith(('http://', 'https://')):
        raise ValueError("M3U8 URL must start with http:// or https://")
    
    # For single stream, we can:
    # Option A: Use the same URL for both xml and m3u
    # Option B: Generate a minimal M3U content and store it
    # Option C: Add a flag in DB to indicate single-stream mode
    
    # Using Option A (simplest):
    add_tuner(name, xml_url=m3u8_url, m3u_url=m3u8_url)

Alternative simpler approach:

  • Add a checkbox: "☑ Single stream mode (M3U8 only)"
  • When checked, auto-populate XML URL with M3U URL value
  • Add help text: "Use the same M3U8 URL for both fields when adding a single stre...

This pull request was created from Copilot chat.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 8 commits February 16, 2026 01:02
Co-authored-by: thehack904 <35552907+thehack904@users.noreply.github.com>
Co-authored-by: thehack904 <35552907+thehack904@users.noreply.github.com>
Co-authored-by: thehack904 <35552907+thehack904@users.noreply.github.com>
Co-authored-by: thehack904 <35552907+thehack904@users.noreply.github.com>
Co-authored-by: thehack904 <35552907+thehack904@users.noreply.github.com>
Co-authored-by: thehack904 <35552907+thehack904@users.noreply.github.com>
Co-authored-by: thehack904 <35552907+thehack904@users.noreply.github.com>
Co-authored-by: thehack904 <35552907+thehack904@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix flash message display duration and behavior Add persistent flash messages and single-stream M3U8 support to tuner management Feb 16, 2026
Copilot AI requested a review from thehack904 February 16, 2026 01:14
Copilot AI and others added 2 commits February 16, 2026 01:23
Co-authored-by: thehack904 <35552907+thehack904@users.noreply.github.com>
Copilot AI changed the title Add persistent flash messages and single-stream M3U8 support to tuner management Add persistent flash messages and M3U8 single-stream mode Feb 16, 2026
@thehack904 thehack904 marked this pull request as ready for review February 16, 2026 01:26
@thehack904 thehack904 merged commit 9302d78 into dev Feb 16, 2026
@thehack904 thehack904 deleted the copilot/fix-flash-message-visibility branch February 16, 2026 19:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants